/** 
 * @Description: 爆炸粒子效果
 * @Author: 程前
 * @Date: 2025-02-10 10:20:09
 * @LastEditors: 程前
 * @LastEditTime: 2025-02-13 15:32:32
 */

import { Viewer, Entity, Matrix4, ScreenSpaceEventType, ScreenSpaceEventHandler, Cartesian2, Color, CircleEmitter, Cartesian3, Quaternion, HeadingPitchRoll, TranslationRotationScale, Scene, ParticleSystem } from "cesium"
import { setEventByHandler, removeEventByHandler, getAssetsFile } from "@/utils"

export default class ExplotEffect {
    private viewer: Viewer;
    private scene: Scene;
    private config: any;
    private particleSystem: ParticleSystem
    private entity: Entity
    private handler: ScreenSpaceEventHandler
    //
    private emitterModelMatrix: Matrix4;
    private translation: Cartesian3;
    private rotation: Quaternion;
    private hpr: HeadingPitchRoll;
    private trs: TranslationRotationScale;

    constructor(viewer: Viewer, handler: ScreenSpaceEventHandler) {
        this.viewer = viewer
        this.handler = handler
        this.config = {
            emissionRate: 5,
            gravity: 0.0,//设置重力参数
            minimumParticleLife: 1,
            maximumParticleLife: 6,
            minimumSpeed: 1.0,//粒子发射的最小速度
            maximumSpeed: 4.0,//粒子发射的最大速度
            startScale: 0.0,
            endScale: 10.0,
            particleSize: 25.0,
        }
        this.emitterModelMatrix = new Matrix4()
        this.translation = new Cartesian3()
        this.rotation = new Quaternion()
        this.hpr = new HeadingPitchRoll()
        this.trs = new TranslationRotationScale()
        this.scene = this.viewer.scene
        this.particleSystem = null

    }

    /**
     * 初始化事件
     */
    initEvents() {
        const leftClick = (event: any) => {
            const ray = this.viewer.camera.getPickRay(event.position);
            const position = this.viewer.scene.globe.pick(ray, this.viewer.scene);
            this.entity = this.viewer.entities.add({
                position,
            });
            this.init();
        }
        setEventByHandler(this.handler, leftClick, ScreenSpaceEventType.LEFT_CLICK)

    }

    /**
     * 创建粒子效果
     */
    private init() {
        this.viewer.clock.shouldAnimate = true;
        this.viewer.scene.globe.depthTestAgainstTerrain = false;
        // this.viewer.trackedEntity = this.entity;
        let particleSystem = this.scene.primitives.add(
            new ParticleSystem({
                image: getAssetsFile('cesium/priticle/explot.png'),//生成所需粒子的图片路径
                //粒子在生命周期开始时的颜色
                startColor: Color.RED.withAlpha(0.7),
                //粒子在生命周期结束时的颜色
                endColor: Color.YELLOW.withAlpha(0.3),
                //粒子在生命周期开始时初始比例
                startScale: this.config.startScale,
                //粒子在生命周期结束时比例
                endScale: this.config.endScale,
                //粒子发射的最小速度
                minimumParticleLife: this.config.minimumParticleLife,
                //粒子发射的最大速度
                maximumParticleLife: this.config.maximumParticleLife,
                //粒子质量的最小界限
                minimumSpeed: this.config.minimumSpeed,
                //粒子质量的最大界限
                maximumSpeed: this.config.maximumSpeed,
                //以像素为单位缩放粒子图像尺寸
                imageSize: new Cartesian2(
                    this.config.particleSize,
                    this.config.particleSize
                ),
                //每秒发射的粒子数
                emissionRate: this.config.emissionRate,
                //粒子系统发射粒子的时间（秒）
                lifetime: 16.0,
                //设置粒子的大小是否以米或像素为单位
                sizeInMeters: true,
                //系统的粒子发射器
                //BoxEmitter 盒形发射器，ConeEmitter 锥形发射器，SphereEmitter 球形发射器，CircleEmitter圆形发射器
                emitter: new CircleEmitter(5.0),

            })
        );
        this.particleSystem = particleSystem;
        this.preUpdateEvent()
    }

    /**
     * 场景渲染
     */
    preUpdateEvent() {
        this.viewer.scene.preUpdate.addEventListener((scene, time) => {
            //发射器地理位置
            this.particleSystem.modelMatrix = this.computeModelMatrix(this.entity, time);
            //发射器局部位置
            this.particleSystem.emitterModelMatrix = this.computeEmitterModelMatrix();
            // 将发射器旋转
            if (this.config.spin) {
                this.config.heading += 1.0;
                this.config.pitch += 1.0;
                this.config.roll += 1.0;
            }
        });
    }

    /**
     * 获取指定时间实体矩阵
     * @param entity 
     * @param time 
     * @returns 
     */
    private computeModelMatrix(entity: Entity, time) {
        return entity.computeModelMatrix(time, new Matrix4());
    }

    /**
     * 发射器位置
     * @returns 
     */
    private computeEmitterModelMatrix() {
        this.hpr = HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, this.hpr);
        this.trs.translation = Cartesian3.fromElements(
            -4.0,
            0.0,
            1.4,
            this.translation
        );
        this.trs.rotation = Quaternion.fromHeadingPitchRoll(this.hpr, this.rotation);

        return Matrix4.fromTranslationRotationScale(
            this.trs,
            this.emitterModelMatrix
        );
    }

    /**
      * 清除事件
      */
    destroy() {
        if (this.handler) {
            this.handler.destroy();
        }
        this.viewer.scene.primitives.remove(this.particleSystem); //删除粒子对象
        this.viewer.entities.remove(this.entity); //删除entity
        this.removeEvent(); //清除事件
        this.viewer.scene.globe.depthTestAgainstTerrain = true;
    }

    removeEvent() {
        this.viewer.scene.preUpdate.removeEventListener(this.preUpdateEvent, this);
        // this.emitterModelMatrix = undefined;
        // this.translation = undefined;
        // this.rotation = undefined;
        // this.hpr = undefined;
        // this.trs = undefined;
    }

}
